package org.dromara.system.utils;

import com.alibaba.fastjson2.JSONObject;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.encrypt.utils.EncryptUtils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/**
 * Jwt工具类
 *
 * @author ruoyi
 */
public class JwtUtils {

    public static final String secretStr = "fu5rqS8EQcN9MceymroDxmHpezUpkEKM";
    public static final byte[] secret = secretStr.getBytes(StandardCharsets.UTF_8);


    public static String getOrderToken(String orderNo, BigDecimal total, String currency, String cancelUrl, String account, String name, long minutes){
        Map<String, Object> claimsMap = new HashMap<>();
        claimsMap.put("No", orderNo);
        claimsMap.put("tl", total);
        claimsMap.put("cy", currency);
        claimsMap.put("at", account);
        claimsMap.put("na", name);
        claimsMap.put("ca", cancelUrl);
        claimsMap.put("exp", LocalDateTime.now().plusMinutes(minutes).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000);
        return createToken(claimsMap, SignatureAlgorithm.HS256);
    }

    public static String getAppToken(Long appId, String secret){
        Map<String, Object> claims = new HashMap<>();
        claims.put("appId", appId);
        claims.put("iat", LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000);
        claims.put("nbf", LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000);
        claims.put("exp", LocalDateTime.now().plusDays(1).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli() / 1000);
        return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS256, secret.getBytes(StandardCharsets.UTF_8)).compact();
    }

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String createToken(Map<String, Object> claims) {
        return Jwts.builder().setClaims(claims).signWith(SignatureAlgorithm.HS512, secret).compact();
    }

    /**
     * 从数据声明生成令牌
     *
     * @param claims 数据声明
     * @return 令牌
     */
    public static String createToken(Map<String, Object> claims, SignatureAlgorithm signature) {
        return Jwts.builder().setClaims(claims).signWith(signature, secret).compact();
    }

    /**
     * 从令牌中获取数据声明
     *
     * @param token 令牌
     * @return 数据声明
     */
    public static Claims parseToken(String token) {
        return Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();
    }

    public static String encryptInfo(String plaintext) {
        try {
            // 获取密钥和 IV（与解密方法相同逻辑）
            String keyStr = secretStr.toLowerCase().substring(0, 32);      // 前 32 字符作为密钥
            String ivStr = secretStr.toLowerCase().substring(secretStr.length() - 16);  // 后 16 字符作为 IV
            // 将密钥和 IV 转换为字节数组（UTF-8 编码）
            byte[] key = keyStr.getBytes(StandardCharsets.UTF_8);
            byte[] iv = ivStr.getBytes(StandardCharsets.UTF_8);
            // 初始化 AES 加密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
            // 加密数据
            byte[] encryptedBytes = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
            // 将加密结果转换为 Base64 字符串
            return Base64.getEncoder().encodeToString(encryptedBytes);
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 解析明文数据
     *
     * @param data 数据
     * @return 数据声明
     */
    public static String parseInfo(String data) {
        try {
            // 获取密钥和 IV
            String keyStr = secretStr.toLowerCase().substring(0, 32); // 前 32 字节作为密钥
            String ivStr = secretStr.toLowerCase().substring(secretStr.length() - 16); // 后 16 字节作为 IV

            // 将密钥和 IV 转换为字节数组
            byte[] key = keyStr.getBytes(StandardCharsets.UTF_8);
            byte[] iv = ivStr.getBytes(StandardCharsets.UTF_8);

            // 解码 Base64 加密数据
            byte[] encryptedBytes = Base64.getDecoder().decode(data);

            // 初始化 AES 解密器
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
            IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);

            // 解密数据
            byte[] decryptedBytes = cipher.doFinal(encryptedBytes);

            // 将解密后的字节数组转换为字符串
            return new String(decryptedBytes, StandardCharsets.UTF_8);
        }catch (Exception e){
            return "";
        }
    }

    public static void main(String[] args) {
        System.out.println(parseInfo("0Dma9xX8y+ozS6E9J7i5/UZqFoggu4EaMDSWZSFp3Ia0d6hULaKimb4UD/+kVMkf5Dp/zkHvvi0nFSHupoFQhW+EuTxsYoHVtwcHR++d04dAhDwaXU3BBrBDQOYsJ2nt/QYxgIHNs9oyhJBft50cb8d3nkkL6eMaWQF67IMdXfMoVaB3GaTdpBRdEjZwDGrC1/bqsu4jHQpcZG5G1B9YiqnbM/vSwfJCf7x+YxFJjKmOx1XmnXMN8/Zh1Hm/SDiR0AZ37zWo0jIo2nH77a6tKOpk52/ytf2PcO6iBppU/bUj60wr//1QwFDMgmK8rysH8mBlICSGiJet6qqdZ5lmivhYTzZOZ8vj9JWmJyVrbwp76nBUPB21/zFGXkbj5g7L+ygRQwqAYR3rWxx3n+FoyXdUFIbrGdR5gOLiKtJxbU4N4V3TuBVL3sj9qsAUpgqUhAPnwOv88H7jyy9f9Jm3P1TXhoZo74Ta0bH/uJP9WcCMx5my7SiLefmIxOQXT6Mx8x2fwXewp/udgKe0ySHTCiOlp8BSp0mOlo0VZb8oFy2ikKESqINf/UYLWeZQRu69EtkhZOr187pazY/E99PiMz/oEPkjVLpTZGcm1TAFwt1LWyAUuu87Lqi+pcK3A+HKl/R+EtYozTTugx4dzqYqfb2waIDop2AzAJy1NIb+CUndxQmdRip7E3JRMLOVSylhTGJowshpM82qCK9iYkKauQ=="));
    }
}
